﻿using System;
using System.Runtime.InteropServices;

namespace Co9320.NamaAlert.Engine
{



	internal struct NtpTimeStamp
	{
		[StructLayout(LayoutKind.Explicit)]
		private struct HelperStruct
		{
			[FieldOffset(0)]
			public uint Value;

			[FieldOffset(0)]
			public byte zero;

			[FieldOffset(1)]
			public byte one;

			[FieldOffset(2)]
			public byte two;

			[FieldOffset(3)]
			public byte three;
		}


		private static readonly DateTime Pivot = new DateTime(1900, 01, 01, 00, 00, 00, DateTimeKind.Utc);

		private uint Second;
		private uint SecondsFraction;

		public NtpTimeStamp(byte[] Data, int StartIndex)
		{
			HelperStruct tmp = new HelperStruct();
			tmp.zero = Data[StartIndex+3];
			tmp.one = Data[StartIndex + 2];
			tmp.two = Data[StartIndex + 1];
			tmp.three = Data[StartIndex];

			Second = tmp.Value;

			tmp = new HelperStruct();

			tmp.zero = Data[StartIndex + 7];
			tmp.one = Data[StartIndex + 6];
			tmp.two = Data[StartIndex + 5];
			tmp.three = Data[StartIndex + 4];

			SecondsFraction = tmp.Value;
		}

		public NtpTimeStamp(DateTime Time)
		{
			TimeSpan t = Time.ToUniversalTime() - Pivot;

			long tmp = t.Ticks / 10000000;
			Second = (uint)tmp;

			tmp = t.Ticks - tmp * 10000000;
			SecondsFraction = (uint)tmp;
		}

		public DateTime ToDateTime()
		{
			long ticks = (long)Second * 10000000L;

			int Digit = 7 - SecondsFraction.ToString("d").Length;
			ticks += (long)(SecondsFraction * (Math.Pow(10, Digit)));

			return Pivot.Add(new TimeSpan(ticks)).ToLocalTime();
		}


		public byte[] ToBinary()
		{
			HelperStruct se = new HelperStruct();
			se.Value = Second;

			HelperStruct sf = new HelperStruct();
			sf.Value = SecondsFraction;

			byte[] buff = new byte[8];

			buff[3] = se.zero;
			buff[2] = se.one;
			buff[1] = se.two;
			buff[0] = se.three;

			buff[7] = sf.zero;
			buff[6] = sf.one;
			buff[5] = sf.two;
			buff[4] = sf.three;

			return buff;
		}

		public override string ToString()
		{
			return this.ToDateTime().ToString();
		}

	}
}